package auditoryUI;

import java.util.ArrayDeque;

import javax.swing.JFrame;

import org.openuat.sensors.SamplesSink;
import org.openuat.sensors.WiTiltRawReader;

public class SimpleWiTiltAdapter extends WiTiltRawReader {

	private static final String port = "COM11";

	private static double x, y, z;

	private final int miDelay = 500;
	// repeat every sec.
	private final int miPeriod = 20;
	
	private final int MAX_POINTS = 4;
	
	//private JFrame t;
	
	private int averageX, averageY, averageZ;
	
	private ArrayDeque<Integer> pointsZ, pointsX, pointsY;

	// private static Vector<Integer> movement;

	public SimpleWiTiltAdapter(SimpleDriver sd) {//
		//t = new JFrame();
		//t.setVisible(true);
		
		pointsX = new ArrayDeque<Integer>(MAX_POINTS);
		pointsY = new ArrayDeque<Integer>(MAX_POINTS);
		pointsZ = new ArrayDeque<Integer>(MAX_POINTS);
		
		try {
			openSerial(port, true);
		} catch (Exception e) {
			e.printStackTrace();
		}
		SimpleWiTiltDataSink[] sinks = new SimpleWiTiltDataSink[3];
		for (int i = 0; i <= 2; i++) {
			sinks[i] = new SimpleWiTiltDataSink(sd);//);
			sinks[i].name = (char) (('X' + i));
		}
		addSink(new int[] { 0, 1, 2 }, sinks);
		simulateSampling();
		
		// tiltDetector.scheduleAtFixedRate( new
		// SimpleWiTiltMonitor(sd),miDelay, miPeriod);
	}

//	 public static void main(String args[]){
//		 SimpleWiTiltAdapter sw = new SimpleWiTiltAdapter();
//	 }

	public double[] getValues() {
		double[] tmp = { x, y, z };
		return tmp;
	}

	// ///////////////////////// test code begins here
	// //////////////////////////////
	private class SimpleWiTiltDataSink implements SamplesSink {

		private char name;

		
		
		private int counter = 0;

		private SimpleDriver sd;

	
		
		

		private SimpleWiTiltDataSink(SimpleDriver sd) {//
			this.sd = sd;
			
		}

		public void addSample(double data, int index) {
			if (name == 'X') {
				pointsX.add((int)data);
			}
			else if (name == 'Y') {
				pointsY.add((int)data);
			}
			else {//Z {
				pointsZ.add((int)data);
			}
			
			if (pointsX.size() == MAX_POINTS){
				averageX = getAverage(pointsX);
				//identifyMovement(Constants.POSITION_WEST, pointsX);
				removeall(pointsX);
			}
			if (pointsY.size() == MAX_POINTS){
				averageY = getAverage(pointsY);
				removeall(pointsY);
			}
			if (pointsZ.size() == MAX_POINTS){
				averageZ = getAverage(pointsZ);
				identifyPosition();
				//identifyMovement(Constants.POSITION_UP, pointsZ);
				removeall(pointsZ);
			}
		}
			

		public void segmentStart(int index) {
			// just ignore for sample code
		}

		public void segmentEnd(int index) {
			// just ignore for sample code
		}
		
		private int getAverage(ArrayDeque<Integer> in){
			int ave = 0;
			Integer[] tmp = new Integer[MAX_POINTS];
			tmp = (Integer[])in.toArray(tmp);
			for (int i = 0; i < MAX_POINTS; i++){
				ave += tmp[i];
			}
			return ave / MAX_POINTS;
		}
		
		private void identifyPosition() {
			//System.out.println(averageX + "--" + averageY + "--" + averageZ);
			if ((averageZ > 440 )
					&& (averageY > 690)
					){//&& averageX > 500 && averageX < 550)
				//t.setTitle("pointing top");
				
				sd.setPosition(Constants.POSITION_SOUTH);
			}
			else if ((averageX > 700)
					&& (averageZ > 450)
					){//&& (averageZ > 530 && averageZ < 550)
				//t.setTitle("pointing left");
				sd.setPosition(Constants.POSITION_WEST);
			}
			else {
				//t.setTitle("normal position");
				sd.setPosition(Constants.POSITION_UP);
			}
			sd.updateMenu();
		}

		private void identifyMovement(int p, ArrayDeque<Integer> in) {
			if (p != sd.getCurrentPosition()){
				removeall(in);
				return;
			}
			Integer[] tmp = new Integer[MAX_POINTS];
			tmp = (Integer[])in.toArray(tmp);
			if ((tmp[0] > 700 && tmp[3] < 100)
					|| (tmp[0] > 700 && tmp[2] < 100)){
				//t.setTitle("Down");
				//sd.tiltDown();
				removeall(in);
			}
			else if ((tmp[0] < 100 && tmp[3] > 700)
					|| tmp[0] < 100 && tmp[2] > 700){
				//t.setTitle("Up");
				//sd.tiltUp();
				removeall(in);
			}
			else {
				in.removeFirst();
			}
		}
		
		private void removeall(ArrayDeque<Integer> in){
			for (Integer i : in){
				in.remove(i);
			}
		}
	}

}
